package com.itserver.service.sys.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itserver.controller.common.LoginController;
import com.itserver.mapper.sys.UserMapper;
import com.itserver.pojo.LoginUser;
import com.itserver.pojo.PageResult;
import com.itserver.pojo.sys.QueryUser;
import com.itserver.pojo.sys.Role;
import com.itserver.pojo.sys.User;
import com.itserver.service.sys.RoleService;
import com.itserver.service.sys.UserService;
import com.itserver.utils.CurrentHolder;
import com.itserver.utils.RequestHeader;
import io.jsonwebtoken.Claims;
import org.jetbrains.annotations.NotNull;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itserver.utils.JwtUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Arrays.stream;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleService roleService;

    @Override
    public PageResult<User> list(@NotNull QueryUser queryUser) {
        PageHelper.startPage(queryUser.getPage(), queryUser.getPageSize());
        List<User> rows = userMapper.list(queryUser);
        Page<User> page = (Page<User>) rows;
        return new PageResult<>(page.getTotal(), rows);
    }

    @Override
    public void add(@NotNull User user) {
        String password = "123456";
        // 生成盐值，第二个参数12表示工作因子，数值越大越安全，但加密速度越慢
        String salt = BCrypt.gensalt();
        // 对密码进行加密
        String hashedPassword = BCrypt.hashpw(password, salt);
        user.setPassword(hashedPassword);
        userMapper.add(user);
    }

    @Override
    public void update(User user) {
        userMapper.update(user);
    }

    @Override
    public void delete(List<Integer> ids) {
        userMapper.delete(ids);
    }

    @Override
    public User getById(Integer id) {
        return userMapper.getById(id);
    }

    @Override
    public LoginUser login(String username, String password) {
        if (username == null || password == null) {
            throw new RuntimeException("账号或密码不能为空！");
        }
        User user = userMapper.getByUser(username);
        if (user != null) {
            // 判断密码 是否一致
            boolean isCheckPWD = BCrypt.checkpw(password, user.getPassword());
            if(!isCheckPWD){
                throw new RuntimeException("密码错误！");
            }

            Map<String, Object> claims = new HashMap<>();
            claims.put("id", user.getId());
            claims.put("nickname", user.getNickname());
            claims.put("username", user.getUsername());
            claims.put("roles", user.getRoles());
            String token = JwtUtils.generateJwt(claims);
            CurrentHolder.setCurrent(user.getUsername());

            claims.put("token", token);
            return new LoginUser(user.getId(),user.getUsername(),user.getNickname(),token,user.getRoles());
        }
        throw new RuntimeException("账号不存在！");
    }

    @Override
    public void register(@NotNull User user) {
        if(user.getUsername().isEmpty() || user.getUsername().equals("null")){
            throw new RuntimeException("请输入正确的用户名");
        }
        User userExist = userMapper.getByUser(user.getUsername());
        if(userExist != null){
            throw new RuntimeException("用户已存在！");
        }
        if(user.getPassword() == null|| user.getPassword().trim().isEmpty()){
            throw new RuntimeException("密码不能为空！");
        }
        String password = user.getPassword().trim();
        // 生成盐值，默认值10表示工作因子，数值越大越安全，但加密速度越慢
        String salt = BCrypt.gensalt();
        // 对密码进行加密
        String hashedPassword = BCrypt.hashpw(password, salt);
        user.setPassword(hashedPassword);
        // 注册用户 默认角色为注册用户
        user.setRoles("8");
        // 设置用户类型
        user.setUserType(0);
        // 默认状态为正常
        user.setStatus(1);
        // 设置备注
        user.setRemark("用户注册");
        userMapper.add(user);
    }

    @Override
    public void resetpwd(@NotNull User user) {
        if(user.getId()==null){
            throw new RuntimeException("用户ID不能为空！");
        }
        // 默认密码123456
        String password = "123456";
        // 生成盐值，默认值10表示工作因子，数值越大越安全，但加密速度越慢
        String salt = BCrypt.gensalt();
        // 对密码进行加密
        String hashedPassword = BCrypt.hashpw(password, salt);
        user.setPassword(hashedPassword);
        userMapper.resetPwd(user);
    }

    @Override
    public LoginController.UserInfo getUserInfo() {
        Integer id = RequestHeader.getUserId();

        User user = userMapper.getById(id);
        LoginController.UserInfo userInfo = new LoginController.UserInfo();
        Map<String,Object> userInfoMap = new HashMap<>();
        userInfoMap.put("id",user.getId());
        userInfoMap.put("username",user.getUsername());
        userInfoMap.put("nickname",user.getNickname());
        userInfoMap.put("roles",user.getRoles());
        userInfoMap.put("rolesName",user.getRolesName());
        userInfoMap.put("sex",user.getSex());
        userInfoMap.put("address",user.getAddress());
        userInfoMap.put("phone",user.getPhone());
        userInfoMap.put("userPic",user.getUserPic());
        userInfoMap.put("email",user.getEmail());
        userInfo.setUser(userInfoMap);

        String roles = user.getRoles();
        if(roles != null && !roles.isEmpty()){
            List<Integer> roleIds = stream(roles.split(",")).map(Integer::parseInt).toList();
            List<Role> roleList = roleService.getByIdsMenu(roleIds);
            List<Map<String,Object> > roleMaps = new ArrayList<>();
            roleList.forEach(role -> {
                Map<String,Object> roleMap = new HashMap<>();
                roleMap.put("role_id",role.getRoleId());
                roleMap.put("role_name",role.getRoleName());
                roleMap.put("role_key",role.getRoleKey());
                roleMaps.add(roleMap);
            });
            userInfo.setRoles(roleMaps);
        }

        return userInfo;
    }

    @Override
    public void updatepwd(LoginController.UpdatePwd body) {
        if(body.getOldPwd() == null || body.getOldPwd().trim().isEmpty()){
            throw new RuntimeException("旧密码不能为空！");
        }
        if (body.getNewPwd() == null || body.getNewPwd().trim().isEmpty()){
            throw new RuntimeException("新密码不能为空！");
        }
        // 旧密码不能与新密码相同
        if(body.getOldPwd().equals(body.getNewPwd())){
            throw new RuntimeException("新密码不能与旧密码相同！");
        }
        // 旧密码
        String oldPassword = body.getOldPwd();
        // 验证旧密码是否正确

        Claims claims = RequestHeader.getUserInfo();
        String username = null;
        if (claims != null) {
            username = claims.get("username").toString();
        }
        User user = userMapper.getByUser(username);

        boolean isCheckPWD = BCrypt.checkpw(oldPassword, user.getPassword());
        if (!isCheckPWD){
            throw new RuntimeException("旧密码错误！");
        }
        String newPassword = body.getNewPwd();

        // 生成盐值，默认值10表示工作因子，数值越大越安全，但加密速度越慢
        String salt = BCrypt.gensalt();
        // 对密码进行加密
        String password = BCrypt.hashpw(newPassword, salt);
        Integer id = RequestHeader.getUserId();
        userMapper.updatepwd(password,id);
    }

}
